home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / Zoners Half-Life Tools / hlcsg / wadcfg.cpp < prev    next >
C/C++ Source or Header  |  2002-12-09  |  14KB  |  461 lines

  1. // AJM: ADDED THIS ENTIRE FILE IN
  2.  
  3. #include "csg.h"
  4. #ifdef HLCSG_WADCFG
  5.  
  6. //#ifdef SYSTEM_WIN32
  7. #if defined(SYSTEM_WIN32) && !defined( __GNUC__ )
  8. #   include "atlbase.h" // win32 registry API
  9. #else
  10. char *g_apppath = NULL; //JK: Stores application path
  11. #endif
  12.  
  13. #define WAD_CONFIG_FILE "wad.cfg"
  14.  
  15. typedef struct wadname_s 
  16. {
  17.     char                    wadname[_MAX_PATH];
  18.     bool                    wadinclude;
  19.     struct wadname_s*       next;
  20. } wadname_t; 
  21.  
  22. typedef struct wadconfig_s
  23. {
  24.     char                    name[_MAX_PATH];
  25.     int                     entries;
  26.     wadname_t*              firstentry;
  27.     wadconfig_s*            next;
  28. } wadconfig_t;
  29.  
  30. wadconfig_t* g_WadCfg;  // anchor for the wadconfigurations linked list
  31.  
  32. bool        g_bWadConfigsLoaded = false;
  33. int         g_wadcfglinecount = 1;
  34.  
  35. //JK: added in
  36. char *g_wadcfgfile = NULL;
  37.  
  38. // little helper function
  39. void stripwadpath (char *str)
  40. {
  41.     char *p = str + strlen (str) - 1;
  42.     while ((*p == ' ' || *p == '\n' || *p == '\t') && p >= str) *p-- = '\0';
  43. }
  44.  
  45. // =====================================================================================
  46. //  WadCfgParseError
  47. // =====================================================================================
  48. void        WadCfgParseError(const char* message, int linenum, char* got)
  49. {
  50.     stripwadpath(got); // strip newlines
  51.  
  52.     Log("Error parsing " WAD_CONFIG_FILE ", line %i:\n"
  53.         "%s, got '%s'\n", linenum, message, got);
  54.  
  55.     Log("If you need help on usage of the wad.cfg file, be sure to check instructions.html that came"
  56.         " in the zip file with these tools.\n"); 
  57.  
  58.     g_bWadConfigsLoaded = false;
  59. }
  60.  
  61. // ============================================================================
  62. //  IsWhitespace
  63. // ============================================================================
  64. bool        IsWhitespace(const char ThinkChar)
  65. {
  66.     if ((ThinkChar == ' ') || (ThinkChar == '\t') || (ThinkChar == '\n') || (ThinkChar == 13) /* strange whitespace char */)
  67.         return true;
  68.  
  69.     return false;
  70. }
  71.  
  72. // ============================================================================
  73. //  Safe_GetToken
  74. // ============================================================================
  75. void        Safe_GetToken(FILE* source, char* TokenBuffer, const unsigned int MaxBufferLength)
  76. {
  77.     char    ThinkChar[1];       // 2 char array = thinkchar and null terminator
  78.     bool    InToken = false;    // are we getting a token?
  79.     bool    InQuotes = false;   // are we in quotes?
  80.     bool    InComment = false;  // are we in a comment (//)?
  81.     //fpos_t* sourcepos;
  82.     long    sourcepos;
  83.  
  84.     TokenBuffer[0] = '\0';
  85.     ThinkChar[1] = '\0';
  86.     
  87.     while(!feof(source))
  88.     {
  89.         if (strlen(TokenBuffer) >= MaxBufferLength)
  90.             return;     // we cant add any more chars onto the buffer, its maxed out
  91.  
  92.         ThinkChar[0] = fgetc(source);   
  93.         
  94.         if (ThinkChar[0] == '\n')              // newline
  95.         {
  96.             g_wadcfglinecount++;
  97.             InComment = false;
  98.         }
  99.  
  100.         if (ThinkChar[0] == ' ')
  101.             return;  
  102.                 
  103.         if (IsWhitespace(ThinkChar[0]) && !InToken)
  104.             continue;   // whitespace before token, ignore
  105.  
  106.         if (ThinkChar[0] == '"')               // quotes
  107.         {
  108.             if(InQuotes)
  109.                 InQuotes = false;
  110.             else
  111.                 InQuotes = true;
  112.             continue;   // dont include quotes
  113.         }
  114.  
  115.         if (ThinkChar[0] == '/')             
  116.         {   
  117.             sourcepos = ftell(source);
  118.             // might be a comment, see if the next char is a forward slash
  119.             if (fgetc(source) == '/')    // if it is, were in a comment
  120.             {
  121.                 InComment = true;
  122.                 continue;
  123.             }
  124.             else // if not, rewind pretend nothing happened...
  125.             {
  126.                 fseek(source, sourcepos, 0);
  127.             }
  128.         }
  129.  
  130.         if (
  131.              (IsWhitespace(ThinkChar[0]) && InToken && !InQuotes) // whitespace AFTER token and not in quotes
  132.           || (InToken && InComment) // we hit a comment, and we have our token
  133.            )
  134.         {
  135.             //printf("[gt: %s]\n", TokenBuffer);
  136.             return;   
  137.         }
  138.  
  139.         if (!InComment)
  140.         {
  141.             strcat(TokenBuffer, ThinkChar);
  142.             InToken = true;
  143.         }
  144.     }
  145. }
  146.  
  147. // =====================================================================================
  148. //  GetWadConfig
  149. //      return true if we didnt encounter any fatal errors
  150. #define MAX_TOKENBUFFER _MAX_PATH
  151. // =====================================================================================
  152. bool        GetWadConfig(FILE* wadcfg, wadconfig_t* wadconfig)
  153. {
  154.     char            TokenBuffer[MAX_TOKENBUFFER];
  155.     wadname_t*      current;
  156.     wadname_t*      previous;
  157.  
  158.     while (!feof(wadcfg))
  159.     {
  160.         Safe_GetToken(wadcfg, TokenBuffer, MAX_TOKENBUFFER);
  161.  
  162.         if (!strcmp(TokenBuffer, "}"))
  163.             return true; // no more work to do
  164.         
  165.         if (!strcmp(TokenBuffer, ";"))
  166.             continue; // old seperator, no longer used but here for backwards compadibility
  167.  
  168.         if (!strcmp(TokenBuffer, "{"))  // wtf
  169.         {
  170.             WadCfgParseError("Expected wadpath (Nested blocks illegal)", g_wadcfglinecount, TokenBuffer);
  171.             return false;
  172.         }
  173.  
  174.         // otherwise assume its a wadpath, make an entry in this configuration
  175.         current = (wadname_t*)malloc(sizeof(wadname_t));
  176.         wadconfig->entries++;
  177.         current->next = NULL;
  178.         current->wadinclude = false;
  179.  
  180.         if (!strcmp(TokenBuffer, "include"))
  181.         {
  182.             current->wadinclude = true;
  183.             Safe_GetToken(wadcfg, TokenBuffer, MAX_TOKENBUFFER);
  184.         }
  185.         
  186.         strcpy(current->wadname, TokenBuffer);
  187.         
  188.         if (!wadconfig->firstentry)
  189.         {
  190.             wadconfig->firstentry = current;
  191.         }
  192.         else
  193.         {
  194.             previous->next = current;
  195.         }
  196.  
  197.         previous = current;
  198.         previous->next = NULL;
  199.     }
  200.  
  201.     safe_snprintf(TokenBuffer, MAX_TOKENBUFFER, "Unexptected end of file encountered while parsing configuration '%s'", wadconfig->name);
  202.     WadCfgParseError(TokenBuffer, g_wadcfglinecount, "(eof)");
  203.     return false; 
  204. }
  205. #undef MAX_TOKENBUFFER
  206.  
  207. // =====================================================================================
  208. //  LoadWadConfigFile
  209. // =====================================================================================
  210. void        LoadWadConfigFile()
  211. {
  212.     FILE*           wadcfg;
  213.     wadconfig_t*    current;
  214.     wadconfig_t*    previous;
  215.  
  216.     char            temp[_MAX_PATH];
  217.  
  218.     //JK: If exists lets use user-defined file
  219.     if (g_wadcfgfile && q_exists(g_wadcfgfile))
  220.     {
  221.         wadcfg = fopen(g_wadcfgfile, "r");
  222.     }
  223.     else // find the wad.cfg file
  224.     {
  225.         char    appdir[_MAX_PATH];
  226.         char    tmp[_MAX_PATH];
  227.                 
  228.         memset(tmp, 0, sizeof(tmp));
  229.         memset(appdir, 0, sizeof(appdir));
  230.  
  231.         // Get application directory (only an approximation on posix systems)
  232.         // try looking in the directory we were run from
  233.         #ifdef SYSTEM_WIN32
  234.         GetModuleFileName(NULL, tmp, _MAX_PATH);
  235.         #else
  236.         safe_strncpy(tmp, g_apppath, _MAX_PATH);
  237.         #endif
  238.     
  239.         ExtractFilePath(tmp, appdir);
  240.         safe_snprintf(tmp, _MAX_PATH, "%s%s", appdir, WAD_CONFIG_FILE);
  241.  
  242.         #ifdef _DEBUG
  243.         Log("[dbg] Trying '%s'\n", tmp);
  244.         #endif
  245.  
  246.         if (!q_exists(tmp))
  247.         {
  248.             // try the Half-Life directory
  249.             #ifdef SYSTEM_WIN32
  250.             {
  251.                 HKEY        HLMachineKey;
  252.                 DWORD       disposition;
  253.                 DWORD       dwType, dwSize;
  254.  
  255.                 // REG: create machinekey
  256.                 RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Valve\\Half-Life"), 0, NULL,  
  257.                                                         0, 0, NULL, &HLMachineKey, &disposition);
  258.                 // REG: get hl dir 
  259.                 dwType = REG_SZ;
  260.                 dwSize = _MAX_PATH;
  261.                 RegQueryValueEx(HLMachineKey, TEXT("InstallPath"), NULL, &dwType, (PBYTE)&appdir, &dwSize);
  262.             }
  263.             
  264.             safe_strncpy(tmp, appdir, _MAX_PATH);
  265.             safe_strncat(tmp, SYSTEM_SLASH_STR, _MAX_PATH); // system slash pointless as this will only work on win32, but anyway...
  266.             safe_strncat(tmp, WAD_CONFIG_FILE, _MAX_PATH);
  267.  
  268.             #ifdef _DEBUG
  269.             Log("[dbg] Trying '%s'\n", tmp);
  270.            #endif
  271.  
  272.             if (!q_exists(tmp))
  273.             #endif  // SYSTEM_WIN32
  274.             {
  275.                 // still cant find it, error out
  276.                 Log("Warning: could not find wad configurations file\n"
  277.                     "Make sure that wad.cfg is in the Half-Life directory or the current working directory\n"
  278.                    );
  279.                 return;
  280.             }
  281.         }
  282.  
  283.         wadcfg = fopen(tmp, "r");
  284.     }
  285.  
  286.     if (!wadcfg)
  287.     {
  288.         // cant open it, die
  289.         Log("Warning: could not open the wad configurations file\n"
  290.             "Make sure that wad.cfg is in the Half-Life directory or the current working directory\n"
  291.             );
  292.         return;
  293.     }
  294.  
  295.     while(!feof(wadcfg))
  296.     {
  297.         Safe_GetToken(wadcfg, temp, MAX_WAD_CFG_NAME);
  298.  
  299.         if (!strcmp(temp, "HalfLifePath="))  // backwards compadibitly
  300.         {
  301.             Safe_GetToken(wadcfg, temp, MAX_WAD_CFG_NAME); 
  302.             Warning("Redundant line in " WAD_CONFIG_FILE ": \"HalfLifePath= %s\" - Ignoring...\n",
  303.                 temp);
  304.             continue;
  305.         }
  306.  
  307.         if (feof(wadcfg))
  308.             break;
  309.  
  310.         // assume its the name of a configuration
  311.         current = (wadconfig_t*)malloc(sizeof(wadconfig_t));
  312.         safe_strncpy(current->name, temp, _MAX_PATH);
  313.         current->entries = 0;
  314.         current->next = NULL;
  315.         current->firstentry = NULL;
  316.  
  317.         // make sure the next char starts a wad configuration
  318.         Safe_GetToken(wadcfg, temp, _MAX_PATH);
  319.         if (strcmp(temp, "{"))
  320.         {
  321.             WadCfgParseError("Expected start of wadfile configuration, '{'", g_wadcfglinecount, temp);
  322.             //Log("[dbg] temp[0] is %i\n", temp[0]);
  323.             fclose(wadcfg);
  324.             return;
  325.         }
  326.  
  327.         // otherwise were ok, get the definition
  328.         if (!GetWadConfig(wadcfg, current))
  329.         {
  330.             fclose(wadcfg);
  331.             return;
  332.         }
  333.  
  334.         // add this config to the list
  335.         if (!g_WadCfg)
  336.         {
  337.             g_WadCfg = current;
  338.         }
  339.         else
  340.         {
  341.             previous->next = current;
  342.         }
  343.  
  344.         previous = current;
  345.         previous->next = NULL;
  346.     }
  347.  
  348.     g_bWadConfigsLoaded = true;
  349. }
  350.  
  351. // =====================================================================================
  352. //  ProcessWadConfiguration
  353. // =====================================================================================
  354. void        ProcessWadConfiguration()
  355. {
  356.     int             usedwads = 0;
  357.     char            szTmp[1024]; // arbitrary, but needs to be large. probably bigger than this.
  358.     wadconfig_t*    config;
  359.     wadname_t*      path;
  360.  
  361.     if(!g_bWadConfigsLoaded) // we did a graceful exit due to some warning/error, so dont complain about it
  362.     {
  363.         Log("Using mapfile wad configuration\n");
  364.         return;
  365.     }
  366.  
  367.     szTmp[0] = 0;
  368.     config = g_WadCfg;
  369.  
  370.     if (!wadconfigname)
  371.         return; // this should never happen
  372.  
  373.     if (!config)
  374.     {
  375.         Warning("No configurations detected in wad.cfg\n"
  376.                 "using map wad configuration");
  377.         return;
  378.     }
  379.  
  380.     while (1)
  381.     {
  382.         if (!strcmp(config->name, wadconfigname))
  383.         {
  384.             path = config->firstentry;
  385.             while (1)
  386.             {
  387.                 if (!path)
  388.                     break;
  389.  
  390.                 Verbose("Wadpath from wad.cfg: '%s'\n", path->wadname);
  391.                 PushWadPath(path->wadname, true);
  392.                 safe_snprintf(szTmp, 1024, "%s%s;", szTmp, path->wadname);
  393.                 usedwads++;
  394.  
  395.                 if (path->wadinclude)
  396.                     g_WadInclude.push_back(path->wadname);
  397.  
  398.                 // next path
  399.                 path = path->next;
  400.             }
  401.             break;  // the user can only specify one wad configuration, were done here
  402.         }
  403.  
  404.         // next config
  405.         config = config->next;
  406.         if (!config)
  407.             break;
  408.     }
  409.     
  410.     if (usedwads)
  411.     {
  412.         Log("Using custom wadfile configuration: '%s' (with %i wad%s)\n", wadconfigname, usedwads, usedwads > 1 ? "s" : "");
  413.         SetKeyValue(&g_entities[0], "wad", szTmp);
  414.         SetKeyValue(&g_entities[0], "_wad", szTmp);    
  415.     }
  416.     else
  417.     {
  418.         Warning("no wadfiles are specified in configuration '%s' --\n"
  419.                 "Using map wadfile configuration", wadconfigname);
  420.         g_bWadConfigsLoaded = false;
  421.     }
  422.  
  423.     return;
  424. }
  425.  
  426. // =====================================================================================
  427. //  WadCfg_cleanup
  428. // =====================================================================================
  429. void        WadCfg_cleanup()
  430. {
  431.     wadconfig_t*    config;
  432.     wadconfig_t*    nextconfig;
  433.     wadname_t*      path;
  434.     wadname_t*      nextpath;
  435.  
  436.     config = g_WadCfg;
  437.     while (config)
  438.     {
  439.         path = config->firstentry;
  440.         while (path)
  441.         {
  442.             nextpath = path->next;
  443.             free(path);
  444.             path = nextpath;
  445.         }
  446.  
  447.         nextconfig = config->next;
  448.         free(config);
  449.         config = nextconfig;
  450.     }
  451.  
  452.     g_WadCfg = NULL;
  453.     g_bWadConfigsLoaded = false;
  454.     return;
  455. }
  456.  
  457.  
  458.  
  459. #endif // HLCSG_WADCFG
  460.  
  461.